package org.example.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.example.annotation.Auth;
import org.example.annotation.Login;
import org.example.config.DeptTree;
import org.example.enums.AuthEnum;
import org.example.utils.JwtUtils;
import org.example.config.MenuTree;
import org.example.constant.MessageConstant;
import org.example.constant.PasswordConstant;
import org.example.constant.StatusConstant;
import org.example.domain.User;
import org.example.domain.UserRole;
import org.example.dto.UserDTO;
import org.example.dto.UserLoginDTO;
import org.example.dto.UserPageQueryDTO;
import org.example.result.PageResult;
import org.example.result.Result;
import org.example.service.DeptService;
import org.example.service.MenuService;
import org.example.service.UserRoleService;
import org.example.service.UserService;
import org.example.utils.OnlineUtil;
import org.example.vo.DeptVo;
import org.example.vo.DriverVo;
import org.example.vo.MenuVo;
import org.example.vo.UserLoginVo;
import org.example.webSocket.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private MenuService menuService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private DeptService deptService;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private WebSocketServer webSocketServer;

    /**
     * 登录
     *
     * @param userLoginDTO
     * @return
     */
    @PostMapping("login")
    @Login()
    public Result login(UserLoginDTO userLoginDTO) {
        //判断验证码
        String ip = request.getRemoteAddr();
        if (userLoginDTO.getCode() == null || "".equals(userLoginDTO.getCode())) {
            return Result.error(-1, MessageConstant.CODE_NOT_FOUND);
        }
        String code = redisTemplate.opsForValue().get("code:" + ip).toString();
        if (!code.equals(userLoginDTO.getCode())) {
            return Result.error(-1, MessageConstant.ERROR_CODE);
        }
        User dbUser = userService.getUser(userLoginDTO);
        if (dbUser == null) {
            return Result.error(500, MessageConstant.ACCOUNT_NOT_FOUND);
        }
        String pwd = DigestUtil.md5Hex(userLoginDTO.getPassword());
        if (!pwd.equalsIgnoreCase(dbUser.getPassword())) {
            return Result.error(500, MessageConstant.PASSWORD_ERROR);
        }
        // 账号锁定判断
        if (Objects.equals(dbUser.getStatus(), StatusConstant.DISABLE)) {
            return Result.error(-1, MessageConstant.ACCOUNT_LOCKED);
        }
        //存token
        String token = JwtUtils.create(dbUser.getId().toString());
        String list = JSONUtil.toJsonStr(menuVoList(dbUser.getId()));
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("list", list);
        //在线人数
        UserLoginVo userLoginVo = UserLoginVo.builder().userId(dbUser.getId()).tel(dbUser.getTel()).loginTime(LocalDateTime.now().toString().split("T")[0] + " " + LocalDateTime.now().toString().split("T")[1]).username(dbUser.getUsername()).ip(ip).build();
        redisTemplate.opsForValue().set("online_user_" + dbUser.getId(), userLoginVo, 2, TimeUnit.HOURS);
        webSocketServer.sendToAllClient(JSONUtil.toJsonStr(OnlineUtil.online(redisTemplate)));
        return Result.success(map);
    }

    public List<MenuVo> menuVoList(Integer userId) {
        List<MenuVo> list = menuService.list(userId);
        return MenuTree.toTree(list);
    }

    @RequestMapping("getUserName/{token}")
    public Result getUserName(@PathVariable("token") String token) {
        JSONObject entries = JwtUtils.of(token);
        String name = userService.getUserName(entries.get("id").toString());
        return Result.success(name);
    }

    /**
     * 查询司机
     */
    @RequestMapping("driverList")
    public Result driverList() {
        List<DriverVo> userRoleList = userRoleService.listAll();
        return Result.success(userRoleList);
    }

    /**
     * 验证码
     *
     * @param response
     * @throws IOException
     */
    @RequestMapping("getCode")
    public void getCode(HttpServletResponse response) throws IOException {
        String ip = request.getRemoteHost();
        //定义图形验证码的长、宽、验证码字符数、干扰元素个数
        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 20);
        String code = captcha.getCode();
        redisTemplate.opsForValue().set("code:" + ip, code, 5, TimeUnit.MINUTES);
        captcha.write(response.getOutputStream());
    }

    /**
     * 查询部门
     */
    @RequestMapping("deptList")
    public Result deptList() {
        List<DeptVo> depts = deptService.listAll();
        List<DeptVo> deptVos = DeptTree.toTree(depts);
        return Result.success(deptVos);
    }


    /**
     * 用户注册
     */
    @RequestMapping("addUser")
    public Result addUser(User user) {
        user.setPassword(DigestUtil.md5Hex(PasswordConstant.DEFAULT_PASSWORD));
        user.setCreateTime(LocalDateTime.now());
        userService.add(user);
        UserRole userRole = new UserRole();
        userRole.setUserId(user.getId());
        userRoleService.add(userRole);
        return Result.success();
    }

    /**
     * 用户页面，集合
     */
    @RequestMapping("userList")
    public Result userList(UserPageQueryDTO userPageQueryDTO) {
        //查询当前用户的菜单列表
        PageResult pageResult = userService.listAll(userPageQueryDTO);
        return Result.success(pageResult);
    }

    /**
     * 用户管理  修改用户信息
     */
    @RequestMapping("updateById")
    public Result updateById(UserDTO userDTO) {
        boolean b = userService.update(userDTO);
        return b ? Result.success() : Result.error(-1, MessageConstant.Update_NOT_FOUND);
    }

    /**
     * 用户管理  删除用户信息
     */
    @RequestMapping("del")
    @Auth(value = {AuthEnum.ADMIN})
    public Result del(Integer id) {
        userRoleService.delete(id);
        return Result.success();
    }
}
